package cn.school.course.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.school.common.exception.ApiException;
import cn.school.common.utils.CourseConstants;
import cn.school.course.dao.CourseConflictDao;
import cn.school.course.dao.CoursePlanDao;
import cn.school.course.entity.Course;
import cn.school.course.entity.CourseConflict;
import cn.school.course.service.CourseConflictService;
import cn.school.course.service.CoursePlanConflictService;
import cn.school.course.service.CourseService;
import cn.school.sys.entity.SysConfig;
import cn.school.sys.entity.TermTime;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @className: 课程-冲突情况ServiceImpl
 * @author: fangjin.tao
 * @date: 2023/1/4
 **/
@Service
public class CourseConflictServiceImpl extends ServiceImpl<CourseConflictDao, CourseConflict> implements CourseConflictService {
	@Autowired
	private CourseService courseService;
	@Autowired
	private CoursePlanDao coursePlanDao;
	@Autowired
	private CoursePlanConflictService coursePlanConflictService;
	
	@Override
	public void saveCourConflictProcess(Date time, Date tetiTermEndDate, String conflictType, List<String> keyList) {
		String groupByKey = null;
		if (CourseConstants.TEACHER_KEY.equals(conflictType)) {
			groupByKey = "cpco_teacher_key";
		} else if (CourseConstants.CLASS_ROOM_KEY.equals(conflictType)) {
			groupByKey = "cpco_room_key";
		} else {
			throw new ApiException("groupByKey 传参错误");
		}
		QueryWrapper<CourseConflict> queryWrapper = new QueryWrapper<>();
		queryWrapper.select(groupByKey);
		// queryWrapper.eq("cpco_is_conflict", 0);
		if (keyList != null && keyList.size() != 0) {
			if (CourseConstants.TEACHER_KEY.equals(conflictType)) {
				queryWrapper.in("cpco_teacher_key", keyList);
			} else if (CourseConstants.CLASS_ROOM_KEY.equals(conflictType)) {
				queryWrapper.in("cpco_room_key", keyList);
			}
		}
		queryWrapper.and((mapper) -> {
			mapper.between("cour_begin_time", time, tetiTermEndDate);
		}).and((mapper) -> {
			mapper.between("cour_end_time", time, tetiTermEndDate);
		});
		queryWrapper.groupBy(groupByKey);
		queryWrapper.having("count(" + groupByKey + ")>1");
		List<Map<String, Object>> maps = this.baseMapper.selectMaps(queryWrapper);
		if (maps != null && maps.size() != 0) {
			for (Map<String, Object> map : maps) {
				String conflictKey = (String) map.get(groupByKey);
				if (CourseConstants.TEACHER_KEY.equals(conflictType)) {
					this.baseMapper.updateByTeacherConfict(conflictKey);
				} else if (CourseConstants.CLASS_ROOM_KEY.equals(conflictType)) {
					this.baseMapper.updateByClassRoomConfict(conflictKey);
				}
			}
		}
		
	}
	
	@Override
	@Transactional
	public void saveBatchCourse(SysConfig courConflictEnable, Date time, Date tetiTermEndDate) {
		// 排课计划产生的预生成课程数据：根据系统参数同步是否冲突的正式课程
		List<CourseConflict> list = this.baseMapper.selecByStatusNotGenner(courConflictEnable);
		if (list != null && list.size() != 0) {
			Course tempCourse = null;
			List<Course> courseList = new ArrayList<>();
			List<Long> courseConflictList = new ArrayList<>();
			for (CourseConflict courseConflict : list) {
				courseConflictList.add(courseConflict.getId());
				tempCourse = new Course();
				BeanUtil.copyProperties(courseConflict, tempCourse);
				tempCourse.setCocoId(courseConflict.getId());
				tempCourse.setCpcoId(courseConflict.getCpcoId());
				tempCourse.setTetiId(courseConflict.getTetiId());
				courseList.add(tempCourse);
			}
			
			List<Long> coplIdList = list.stream().map(CourseConflict::getCoplId).collect(Collectors.toList());
			this.baseMapper.updateToStautAlreadyGenner(courseConflictList);
			this.coursePlanDao.updateToStautAlreadyGenner(coplIdList); // 排课计划状态更新 - 为 - 已生成
			this.courseService.saveBatch(courseList);
			
		}
		
		
	}
	
	@Override
	@Transactional
	public void updateConflictCase(TermTime termTime, List<String> allTeacherKeyeyList, List<String> allRommKeyList) {
		List<Long> idList = this.baseMapper.selectIdByKeyList(allTeacherKeyeyList, allRommKeyList);
		// ===========   课程冲突处理 ===============
		// 直接更新为不冲突的情况
		if (idList != null && idList.size() != 0) {
			this.baseMapper.updateToNotConflict(idList);
		}
		
		// 重新检测，动态列新冲突情况
		// 教员分身冲突-情况处理
		// 教室空间占用冲突-情况处理
		this.saveCourConflictProcess(DateUtil.beginOfDay(termTime.getTetiTermBeginDate()),
				DateUtil.endOfDay(termTime.getTetiTermEndDate()), CourseConstants.TEACHER_KEY, allTeacherKeyeyList);
		// 教室空间占用冲突-情况处理
		this.saveCourConflictProcess(DateUtil.beginOfDay(termTime.getTetiTermBeginDate()),
				DateUtil.endOfDay(termTime.getTetiTermEndDate()), CourseConstants.CLASS_ROOM_KEY, allRommKeyList);
		
		// ========== 排课计划冲突处理 ===============
		List<Long> coursePlanConflictIdList = this.coursePlanConflictService.selectIdByKeyList(allTeacherKeyeyList, allRommKeyList);
		if (coursePlanConflictIdList != null && coursePlanConflictIdList.size() != 0) {
			coursePlanConflictService.updateToNotConflict(coursePlanConflictIdList);
		}
		// 教员分身冲突-情况处理
		this.coursePlanConflictService.saveCpcoConflictProcess(DateUtil.beginOfDay(Calendar.getInstance().getTime()),
				DateUtil.endOfDay(termTime.getTetiTermEndDate()), CourseConstants.TEACHER_KEY, allTeacherKeyeyList);
		// 教室空间占用冲突-情况处理
		this.coursePlanConflictService.saveCpcoConflictProcess(DateUtil.beginOfDay(Calendar.getInstance().getTime()),
				DateUtil.endOfDay(termTime.getTetiTermEndDate()), CourseConstants.CLASS_ROOM_KEY, allRommKeyList);
		
	}
	
	
}
